import time
import requests
from django.conf import settings

class LLMFactory:
    """大模型服务工厂"""
    
    @staticmethod
    def get_llm_service():
        """获取DeepSeek大模型服务实例"""
        return DeepseekLLMService()

class BaseLLMService:
    """大模型服务基类，定义统一接口"""
    
    def chat_completion(self, messages, temperature=0.7, max_tokens=800):
        """聊天补全API"""
        raise NotImplementedError("子类必须实现此方法")

class DeepseekLLMService(BaseLLMService):
    """DeepSeek大模型服务"""
    
    def __init__(self):
        self.api_key = settings.DEEPSEEK_API_KEY
        self.api_url = "https://api.deepseek.com/v1/chat/completions"  # 请确认这是正确的API URL
        self.max_retries = 3  # 最大重试次数
    
    def chat_completion(self, messages, temperature=0.7, max_tokens=800):
        """使用DeepSeek API进行聊天补全"""
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": "deepseek-chat",
            "messages": messages,
            "temperature": temperature,
            "max_tokens": max_tokens,
            "top_p": 1
        }
        
        # 添加重试逻辑
        retries = 0
        while retries < self.max_retries:
            try:
                print(f"尝试调用DeepSeek API (尝试 {retries + 1}/{self.max_retries})...")
                
                response = requests.post(
                    self.api_url, 
                    headers=headers, 
                    json=payload,
                    timeout=60  # 增加超时时间
                )
                
                if response.status_code == 200:
                    result = response.json()
                    return {
                        'content': result['choices'][0]['message']['content'],
                        'status': 'success'
                    }
                else:
                    print(f"API请求失败，状态码: {response.status_code}")
                    print(f"错误信息: {response.text}")
                    
                    # 如果是服务器错误(5xx)，重试
                    if 500 <= response.status_code < 600:
                        retries += 1
                        if retries < self.max_retries:
                            wait_time = 2 ** retries  # 指数退避策略
                            print(f"等待 {wait_time} 秒后重试...")
                            time.sleep(wait_time)
                            continue
                    
                    return {
                        'content': f"API请求失败: {response.text}",
                        'status': 'error'
                    }
                    
            except requests.exceptions.Timeout:
                print(f"请求超时 (尝试 {retries + 1}/{self.max_retries})")
                retries += 1
                if retries < self.max_retries:
                    wait_time = 2 ** retries  # 指数退避策略
                    print(f"等待 {wait_time} 秒后重试...")
                    time.sleep(wait_time)
                else:
                    return {
                        'content': "DeepSeek API请求超时，请稍后再试。",
                        'status': 'error'
                    }
            except Exception as e:
                print(f"DeepSeek API调用失败: {str(e)}")
                return {
                    'content': f"API调用失败: {str(e)}",
                    'status': 'error'
                }
        
        # 如果所有重试都失败
        return {
            'content': "多次尝试后无法连接到DeepSeek API，请检查网络或稍后再试。",
            'status': 'error'
        }

    def get_fallback_response(self, messages):
        """当API调用失败时提供基本回复"""
        user_message = "无消息"
        
        # 查找最后一条用户消息
        for msg in reversed(messages):
            if msg["role"] == "user":
                user_message = msg["content"]
                break
        
        # 提供基本回复
        if "推荐" in user_message and "电影" in user_message:
            return "抱歉，我现在无法连接到推荐服务。你可以尝试浏览我们的热门电影列表，或者稍后再试。"
        elif "帮助" in user_message or "怎么" in user_message:
            return "抱歉，我当前无法提供详细帮助。请尝试浏览网站或稍后再试。"
        else:
            return "抱歉，我暂时无法处理您的请求。这可能是由于网络连接问题，请稍后再试。" 